package io.github.uicdb.liba.api.multiblock;

import io.github.uicdb.liba.api.register.BlockEntityTypeHolder;
import io.github.uicdb.liba.api.register.MenuHolder;
import io.github.uicdb.liba.api.util.LazyUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.Nullable;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.concurrent.atomic.AtomicReference;

@ParametersAreNonnullByDefault
public class ControllerBlock extends Block implements EntityBlock {
    private final BlockEntityTypeHolder<? extends ControlBlockEntity> blockEntityTypeHolder;
    private final MenuHolder<? extends AbstractContainerMenu> menuHolder;

    public ControllerBlock(Properties properties, BlockEntityTypeHolder<? extends ControlBlockEntity> blockEntityTypeHolder, MenuHolder<?> menuHolder) {
        super(properties);
        this.blockEntityTypeHolder = blockEntityTypeHolder;
        this.menuHolder = menuHolder;
    }

    public BlockEntityTypeHolder<? extends ControlBlockEntity> getBlockEntityTypeHolder() {
        return blockEntityTypeHolder;
    }

    @Nullable
    @Override
    public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {
        if (blockEntityTypeHolder != null)
            return blockEntityTypeHolder.create(pPos, pState);
        return null;
    }

    @Override
    public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
        AtomicReference<InteractionResult> result = new AtomicReference<>(InteractionResult.SUCCESS);
        if (blockEntityTypeHolder == null || menuHolder == null) return InteractionResult.FAIL;
        if (!pLevel.isClientSide && pPlayer instanceof ServerPlayer serverPlayer) {
            pLevel.getBlockEntity(pPos, blockEntityTypeHolder.get()).ifPresent(type -> {
                if (type.isFormed())
                    menuHolder.open(serverPlayer,new TranslatableComponent("title.block." + getRegistryName().getPath()), pPos);
                else {
                    boolean tryFormed = type.tryFormMultiBlock(serverPlayer.getItemInHand(pHand));
                    if (!tryFormed) result.set(InteractionResult.FAIL);
                }
            });
        }
        return result.get();
    }

    @Nullable
    @Override
    public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level pLevel, BlockState pState, BlockEntityType<T> pBlockEntityType) {
        return LazyUtil.getTicker();
    }
}
